﻿/**
 * @file guild_service_basic.h
 * @date 2021/04/13 20:34
 *
 * @author harrybao (harrybao@123u.com)
 *
 * @brief 公会管理器
 *
 * @version v1.0.0
 *
 * @copyright Copyright © 2021 All Rights Reserved 上海欢乐互娱网络科技有限公司
 *
 * @par history:
 * <table>
 * <tr><th>Date                     <th>Version     <th>Author <th>Description
 * <tr><td>2021/04/13 20:34         <td>1.0.0       <td>harrybao
 * <td>创建初始版本
 * </table>
 */

// #ifndef GUILD_SERVICE_BASIC_H
// #define GUILD_SERVICE_BASIC_H

#pragma once

#include <unordered_map>
#include <set>

#include "AnnounceMsg_struct.h"
#include "AnnounceData_struct.h"
#include "GuildModuleBrief_struct.h"

#include "fwd.h"
#include "guild/module/guild_module.h"
#include "guild/module/guild_module_deleter.hpp"
#include "guild/module/guild_module_loader.hpp"
#include "guild/module/guild_module_saver.hpp"
#include "singleton.hpp"

// struct GuildBrief;

namespace guild_service {

/**
 * @brief 公会管理器类
 *
 * 提供id索引，删除、添加等功能
 */
class GuildServiceBasic final {
 public:
  GuildServiceBasic() = default;
  ~GuildServiceBasic() = default;

  GuildServiceBasic(const GuildServiceBasic &) = delete;
  GuildServiceBasic(GuildServiceBasic &&) = delete;
  const GuildServiceBasic &operator=(const GuildServiceBasic &) = delete;
  const GuildServiceBasic &operator=(GuildServiceBasic &&) = delete;

 public:
  /**
   * @brief 根据角色唯一id获取公会id
   *
   * @param role_uuid 角色唯一id
   * @param guild_id 公会id
   * @return true 获取成功
   * @return false 获取失败
   */
  guild_id_type GetGuildIdByRole(const role_uuid_type role_uuid) const;

  /**
   * @brief 添加公会
   *
   * @param guild_id
   * @return true
   * @return false
   */
  bool AddGuild(const guild_id_type &guild_id);

  /**
   * @brief 移除公会
   *
   * @param guild_id
   * @return true
   * @return false
   */
  bool RemoveGuild(const guild_id_type guild_id);

  /**
   * @brief 添加角色到公会id的映射
   *
   * @param role_uuid
   * @return true
   * @return false
   */
  bool AddGuildRole(const guild_id_type guild_id,
                    const role_uuid_type role_uuid);

  /**
   * @brief 移除角色到公会id的映射
   *
   * @param guild_id
   * @param role_uuid
   * @return true
   * @return false
   */
  bool RemoveGuildRole(const guild_id_type guild_id,
                       const role_uuid_type role_uuid);

 public:
  using ForeachGuildCallbackType =
      std::function<void(const guild_id_type&)>;  ///< 遍历公会回调函数类型

  /**
   * @brief 遍历所有公会
   *
   * @param callback
   */
  void ForeachGuild(const ForeachGuildCallbackType &callback);

 public:
  /**
   * @brief 异步加载公会
   *
   * @return true
   * @return false
   */
  bool LoadGuildAsync();

  /**
   * @brief 同步递增公会id
   *
   * @param guild_id 公会id
   * @return true 递增成功
   * @return false 递增失败
   */
  static bool IncrGuildLastId(guild_id_type &guild_id);

  /**
   * @brief 同步删除公会
   *
   * @param guild 公会
   * @return true
   * @return false
   */
  inline static bool DeleteGuildToRedis(const guild_id_type guild_id) {
    return guild_service::detail::DeleteGuild(kGuildServiceBasicName, guild_id);
  }

  /**
   * @brief 同步删除公会模块
   *
   * @tparam Serializer 模块序列化类模板
   * @param guild 公会
   * @return true
   * @return false
   */
  inline static bool DeleteGuildModuleToRedis(const Guild &guild,
                                              const std::string &module_name) {
    return detail::DeleteGuildModule(kGuildServiceBasicName, guild.id,
                                     module_name);
  }

  /**
   * @brief 同步保存公会角色
   *
   * @param op redis操作
   * @param role_uuid 角色唯一id
   * @param guild_id 公会id
   * @return true 保存成功
   * @return false 保存失败
   */
  static bool SaveGuildRoleToRedis(const std::string &op,
                                   const role_uuid_type role_uuid,
                                   const guild_id_type guild_id);

  /**
   * @brief 保存最后创建的公会id
   *
   * @param guild_id 公会id
   * @return true 保存成功
   * @return false 保存失败
   */
  static bool SaveLastGuildIdToRedis(const guild_id_type guild_id);

  /**
   * @brief 构造一个公会
   *
   * @param guild_id
   * @return Guild
   */
  static Guild NewGuild(const guild_id_type guild_id = 0ull);

 public:
  /**
   * @brief 是否是同一个公会
   *
   * @param role_uuid1
   * @param role_uuid2
   * @return true
   * @return false
   */
  bool InSameGuild(const role_uuid_type role_uuid1,
                   const role_uuid_type role_uuid2);

  /**
   * @brief 是否有公会
   * @param role_uuid 角色唯一id
   * @return 是否有公会
   */
  bool HasGuild(const role_uuid_type role_uuid) const;

  /**
   * @brief 公会是否合法
   *
   * @param guild
   * @return true
   * @return false
   */
  static bool IsValidGuild(const Guild &guild);

 public:
  /**
   * @brief 公会总数量
   *
   * @return std::size_t
   */
  // inline std::size_t Size() const { return guilds_.size(); }

  /**
   * @brief 公会名字是否存在
   *
   * @param name 公会名字
   * @return true 公会名字存在
   * @return false 公会名字不存在
   */
  bool IsGuildNameExisted(const std::string &name) const;

 private:
  /**
   * @brief 异步加载公会Id
   *
   * @return true
   * @return false
   */
  bool LoadGuildIdAsync();

  /**
   * @brief 异步加载公会模块
   *
   * @return true 加载成功
   * @return false 加载失败
   */
  bool LoadGuildModuleAsync();

  void LoadGuildModuleBriefCallback(const redis_result_type &result, std::uint64_t udata);

 private:
  /**
   * @brief 同步从redis根据角色唯一id获取公会id
   *
   * @param role_uuid 角色唯一id
   * @return false 获取失败
   */
  bool GetGuildIdByRoleFromRedis(const role_uuid_type role_uuid,
                                 guild_id_type &guild_id) const;

 private:
  /// 所有公会的简略信息
  std::unordered_map<guild_id_type, GuildModuleBrief> guild_to_brief_dic_;
  /// 所有公会容器
  std::set<guild_id_type> guild_set_;
  /// 角色id查找公会id容器
  std::unordered_map<role_uuid_type, guild_id_type> role_to_guild_dic_;
  // std::unordered_map<guild_id_type, std::string>
  //     guild_to_name_;  ///< 公会id查找公会名字容器
};

///
#define GuildServiceBasicSingleton \
  (common::singleton<guild_service::GuildServiceBasic>::instance())

}  // namespace guild_service

// #endif  // GUILD_SERVICE_BASIC_H